home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / VGAREGS.ZIP / VGAREGS.TXT
Encoding:
Text File  |  1996-04-26  |  41.5 KB  |  1,560 lines

  1.  
  2.                          Programming the VGA Registers
  3.  
  4.                       by Boone (boone@ucsd.edu), March '94
  5.  
  6.  
  7.    The IBM PC has long been slammed by owners of other computers which come 
  8.  
  9. with superior graphics capabilities built right into hardware.  The PC is a 
  10.  
  11. strange beast to program in general, and when it comes to graphics the 
  12.  
  13. programmer doesn't get much help from the video hardware.  However, there are 
  14.  
  15. quite a few neat tricks you can do using the VGA registers, as I'm sure you're 
  16.  
  17. aware.  The trick is knowing just which registers to use and how to use them to 
  18.  
  19. achieve the desired results.  In particular, precise timing is necessary to 
  20.  
  21. avoid screen flicker and/or "snow".  The registers on your video card are 
  22.  
  23. necessary for just about any communication with the VGA besides basic 
  24.  
  25. reading/writing of pixels.  Some of the registers are standard, which are the 
  26.  
  27. ones we will be discussing here.  Most SVGA chipsets have their own special 
  28.  
  29. functions associated with different registers for things such as bank 
  30.  
  31. switching, which is part of what makes trying to write SVGA programs so 
  32.  
  33. difficult.  The registers are also used to set the various attributes of each 
  34.  
  35. video mode: horizontal and vertical resolution, color depth, refresh rate, 
  36.  
  37. chain-4 mode, and so on.  Luckily, BIOS handles all this for us and since we 
  38.  
  39. only need to set the video mode once at program start-up and once at exit, you 
  40.  
  41. should need to mess with these particular functions too much, unless you are 
  42.  
  43. using a special mode, such as mode X.  (See the mode X section for more info on 
  44.  
  45. all this.)  If you want to experiment with the video mode registers, ftp 
  46.  
  47. yourself a file called TWEAK*.* (my version is TWEAK10.ZIP).  For now we'll 
  48.  
  49. just assume the video mode has already been set to whatever mode you wish.
  50.  
  51.    One of the most common techniques used by game programmers is fade in/out.  
  52.  
  53. A clean fade is simple but very effective.  Suprisingly, even big-budget games 
  54.  
  55. like Ultima VII often have a lot of screen noise during their fades.  With a 
  56.  
  57. little effort you can easily write your own noise-free fade routines.  There's 
  58.  
  59. nothing like giving a professional first impression on your intro screen, since 
  60.  
  61. the fade-in is likely to be the very first thing they see of your program.
  62.  
  63.    BIOS is much to slow for this timing-critical opperation, so we'll have to 
  64.  
  65. get down and dirty with our VGA card.  Fading is a fairly simple process.  As 
  66.  
  67. you should know, the VGA palette consists of 256 colors with 3 attributes for 
  68.  
  69. each color: red, green and blue.  Every cycle of the fade, we have to go 
  70.  
  71. through all 768 attributes and if it is larger than 0 subtract one.  We'll use 
  72.  
  73. regsiters 3C8h and 3C9h for palette opperations.  The operation for sending a 
  74.  
  75. palette to the card is straight-forward: send a 0 to port 3C8h and then your 
  76.  
  77. 768 byte buffer to port 3C9h.  This is good enough for setting the palette at 
  78.  
  79. the start of your program, but of course it has to go in a loop for the fade, 
  80.  
  81. since you'll have to do this 256 times, subtracting one from each non-zero 
  82.  
  83. member of the buffer.  The pseudo-code looks something like this:
  84.  
  85.  
  86.    constant PALSIZE = 256*3;
  87.  
  88.    unsigned character buffer[PALSIZE];
  89.  
  90.    boolean done;
  91.  
  92.    counter i,j;
  93.  
  94.  
  95.       for j = 255 to 0
  96.  
  97.        {
  98.  
  99.          for i = 0 to PALSIZE-1
  100.  
  101.             if buffer[i] > 0
  102.  
  103.                buffer[i] = buffer[i] - 1;
  104.  
  105.  
  106.          output 0 to port 3C8h;
  107.  
  108.          for i = 0 to PALSIZE-1
  109.  
  110.             output buffer[i] to port 3C9h;
  111.  
  112.        }
  113.  
  114.  
  115.    Easy enough, right?  If you convert this to the language of your choice it 
  116.  
  117. should run fine.  (Make sure you have the buffer pre-loaded with the correct 
  118.  
  119. palette, however, or you will get very strange results...)  But you'll notice 
  120.  
  121. the "snow" mentioned earlier.  Depending on your video card, this could mean 
  122.  
  123. that you see no noise at all to fuzz covering your entire screen.  Even if it 
  124.  
  125. look fine on your system, however, we want to make sure it will be smooth on 
  126.  
  127. *all* setups it could potentially be run on.  For that we're going to have to 
  128.  
  129. ask the video card when it's safe to send the palette buffer to the card, and 
  130.  
  131. for that we'll need the retrace register.
  132.  
  133.    Putting aside palette concerns for a moment, I'll briefly cover the retrace 
  134.  
  135. on your video card.  (See the next section of this article for a more in-depth 
  136.  
  137. discussion of this.)  Bascially the vertical retrace is a short time in which 
  138.  
  139. the screen is not being updated (from video memory to your monitor) and you can 
  140.  
  141. safely do writes to your video memory or palette without worrying about getting 
  142.  
  143. snow, flicker, tearing, or other unwanted side-effects.  This is a pretty quick 
  144.  
  145. period (retrace occurs 60 to 70 times a second) so you can't do too much at 
  146.  
  147. once.
  148.  
  149.    Returning to our fade: we want to update the palette during the vertical 
  150.  
  151. retrace.  The value we want is bit 3 of register 3DAh.  While that bit is zero 
  152.  
  153. we're safe to write.  The best practice in this case is to wait for the bit to 
  154.  
  155. change to one (screen is being traced) and then the instant it changes to 0, 
  156.  
  157. blast all our new video info to the card.  It won't be necessary in this case 
  158.  
  159. since all we are doing is fading the palette and then waiting for the next 
  160.  
  161. retrace, but if you're doing animation or playing music at the same time 
  162.  
  163. you'll want to include this extra bit of code as a safety net.  Otherwise you 
  164.  
  165. might detect the 0 in the refresh bit at the very last instant of the retrace 
  166.  
  167. and end up writing while the screen is being traced.  The pseudo-code now goes 
  168.  
  169. like this:
  170.  
  171.  
  172.       for j = 255 to 0
  173.  
  174.        {
  175.  
  176.          for i = 0 to PALSIZE-1
  177.  
  178.             if buffer[i] > 0
  179.  
  180.                buffer[i] = buffer[i] - 1;
  181.  
  182.  
  183.          while bit 3 of port 3DAh is 0
  184.  
  185.             no opperation;
  186.  
  187.          while bit 3 of port 3DAh is 1
  188.  
  189.             no opperation;
  190.  
  191.  
  192.          output 0 to port 3C8h;
  193.  
  194.          for i = 0 to PALSIZE-1
  195.  
  196.             output buffer[i] to port 3C9h;
  197.  
  198.        }
  199.  
  200.  
  201.    That's it!  All that's left is for you to implement it in your favorite 
  202.  
  203. language.  However, I can hear the cries right now: "Code!  Give us some real 
  204.  
  205. assembly code we can use!"  I'm reluctant to provided it as this is the exact 
  206.  
  207. sort of thing that is easy to cut and paste into your program without knowing 
  208.  
  209. how it works.  However, I'll give you the unoptimized main loop in 80x86 
  210.  
  211. assembly as this may be clearer to you that my explanation or pseudo-code.  Two 
  212.  
  213. things to remember about this code: it is optimized enough to be smooth on any 
  214.  
  215. video card (or any that I've seen, anyway) assuming that the fade is the _only_ 
  216.  
  217. thing going on.  There's some other things you may want to change if you plan 
  218.  
  219. to say, play music during this process.  Secondly, you'll need to have the 
  220.  
  221. current palette loaded into the buffer beforehand.  You could read it from the 
  222.  
  223. VGA card using either registers or BIOS, but this is both slow and (in my 
  224.  
  225. oppinion) sloppy coding.  You should *never* ask the video card about anything 
  226.  
  227. (excluding retrace) that you could keep track of yourself.  In the case of the 
  228.  
  229. palette, you probably already loaded it from disk anyway, or if you are using 
  230.  
  231. the default palette <cough, gag, choke> just read the values once and store 
  232.  
  233. them in your executable or in a resource file.
  234.  
  235.  
  236.      palbuf   DB                  768 DUP (?)
  237.  
  238.      fadecnt  DW                  040h
  239.  
  240.  
  241. ; At this point, you should:
  242.  
  243. ;  1) have the video mode set
  244.  
  245. ;  2) have palbuf loaded with the current palette
  246.  
  247. ;  3) have something on the screen to fade!
  248.  
  249.  
  250. fadeloop:
  251.  
  252.  
  253.      xor      al,al               ; used for comparisons and port 3D8h
  254.  
  255.      mov      cx,768              ; loop counter
  256.  
  257.      mov      si,offset palbuf    ; save palette buffer in si
  258.  
  259.  
  260. decloop:
  261.  
  262.      mov      dl,[si]              ; put next pal reg in dx
  263.  
  264.      cmp      al,dl                ; is it 0?
  265.  
  266.      je       next                 ; nope...
  267.  
  268.      dec      dl                   ; yes, so subtract one
  269.  
  270.      mov      [si],dl              ; put it back into palette buffer
  271.  
  272.  
  273. next:
  274.  
  275.      dec      cx                   ; decrement counter
  276.  
  277.      inc      si                   ; increment our buffer
  278.  
  279.      cmp      cx,0
  280.  
  281.      jne      decloop              ; not done yet, so loop around
  282.  
  283.  
  284.      mov      cx,768              ; reset for palette output
  285.  
  286.      sub      si,768              ; reset palbuf pointer
  287.  
  288.      mov      dx,03c8h
  289.  
  290.      out      dx,al               ; inform VGA of palette change
  291.  
  292.      inc      dx                  ; DX = 3C8h + 1 = 3C9h
  293.  
  294.  
  295.      mov      ch,02h              ; do outter loop 2 times
  296.  
  297.      mov      dx,03dah            ; prepare refresh register
  298.  
  299.      mov      bx,03c9h            ; prepare palette reg (for quick loading)
  300.  
  301.  
  302.      cli                          ; disable interrupts!
  303.  
  304.  
  305. outloop:
  306.  
  307.      mov      cl,80h              ; do inner loop 128 times
  308.  
  309.  
  310.      in       al,dx               ; wait for current retrace to end
  311.  
  312.      test     al,08h
  313.  
  314.      jnz      $-5
  315.  
  316.  
  317.      in       al,dx               ; wait for current screen trace to end
  318.  
  319.      test     al,08h
  320.  
  321.      jz       $-5
  322.  
  323.  
  324.      mov      dx,bx               ; load up the palette change register
  325.  
  326.  
  327. innerloop:
  328.  
  329.      mov      al,[si]             ; load next byte of palbuf
  330.  
  331.      out      dx,al               ; send it to the VGA card
  332.  
  333.      dec      cl                  ; decrement counter
  334.  
  335.      inc      si                  ; increment palbuf pointer
  336.  
  337.      cmp      cl,0
  338.  
  339.      jne      innerloop           ; loop while not done
  340.  
  341.  
  342.      dec      ch                  ; decrement outer loop counter
  343.  
  344.      cmp      ch,0
  345.  
  346.      jne      outloop             ; loop while not done
  347.  
  348.  
  349.      sti                          ; restore interrupts
  350.  
  351.  
  352.      mov      ax,fadecnt          ; entire palette has been sent
  353.  
  354.      dec      ax                  ; so check fade loop 
  355.  
  356.      mov      fadecnt,ax
  357.  
  358.      cmp      ax,0                ; ready to quit?
  359.  
  360.      jne      fadeloop            ; nope, keep fading!
  361.  
  362.  
  363.  
  364.    I should add a few comments about this code segment.  First of all, it 
  365.  
  366. assumes you want to fade every color all the way down.  You may only want to 
  367.  
  368. fade certain sections of the palette (if your screen was only using a certain 
  369.  
  370. number of colors) or maybe your palette is low-intensity so you don't need to 
  371.  
  372. go the full 256 loops to get every color down to 0.  It also goes by ones, so 
  373.  
  374. if you want a faster fade you can have it subtract two from each attribute.  
  375.  
  376. If you want to fade to a certain color other than black (for instance, fade to 
  377.  
  378. red such as the "getting hit" effect in Doom), you'll need to check if each 
  379.  
  380. attribute is above or below your target color and increment or decrement 
  381.  
  382. accordingly.  Also, you may have noticed something in the code absent from the 
  383.  
  384. pseudo-code: it only sends 128 colors to the card each retrace!  This is 
  385.  
  386. because if you use all 256 the next retrace may start before you get all colors 
  387.  
  388. sent to the video card, thanks to the unoptimized code.  Some recommend as 
  389.  
  390. little as 64 colors per retrace, however I've found 128 to be okay and 
  391.  
  392. certainly much faster.  The above code works for any VGA-equiped machine, 
  393.  
  394. regardless of processor, but you'll probably want to compress all the IN and 
  395.  
  396. OUT loops into REP INSB/OUTSB, REP INSW/OUTSW, or REP INSD/OUTSD instructions 
  397.  
  398. depending upon the minimum processor requirement for your game/demo.
  399.  
  400.    I won't describe fading in since it's the same sort of thing, and I'm sure 
  401.  
  402. you can figure it out once you know how to use the registers themselves.  It's 
  403.  
  404. a little more complicated since you need a second buffer of target values for 
  405.  
  406. your attributes, but otherwise quite similar.
  407.  
  408.  
  409.    Next up is vertical retrace.  This is simply one of many read registers on 
  410.  
  411. your VGA, but it happens to be one of the most useful for animation and palette 
  412.  
  413. fades (as shown above).  Here's a quick rundown of what exactly the vertical 
  414.  
  415. retrace is, and why it's useful.
  416.  
  417.    There's an electron gun in the back of your monitor that keeps the pixels 
  418.  
  419. "refreshed" with their correct values every 1/60th of a second or so.  It fires 
  420.  
  421. electrons at each pixel, row by row.  The horizontal retrace is the time it 
  422.  
  423. takes it to return from the right side of the screen after it has traced a row.  
  424.  
  425. This is a very short time and I wouldn't worry about that too much right now, 
  426.  
  427. as it is only useful for very specialized (and quite tricky) hardware effects.
  428.  
  429. More useful, however, is the vertical retrace which occurs when the electron 
  430.  
  431. gun reaches the bottom of the screen (one entire screen traced) and it returns 
  432.  
  433. diagonally to the upper-right hand corner of the screen.  During this time you 
  434.  
  435. are free to update anything you like having to do with video with no noise or 
  436.  
  437. interference (since nothing on the screen is being updated).  This is a fairly 
  438.  
  439. short amount of time, though, so whatever you want to do you better do it 
  440.  
  441. _quickly_.  For animation, you'll usually want to keep a second buffer in main 
  442.  
  443. memory (remember that video RAM is quite slow compared to main RAM) which you 
  444.  
  445. can use to write your animations to.  When the vertical retrace occurs, you'll 
  446.  
  447. want to blast the entire thing to the VGA as quickly as possible, using a 
  448.  
  449. memory copy instruction.  You can find more on this in articles which cover 
  450.  
  451. animation.
  452.  
  453.  
  454.    Lastly I'll briefly describe the VGA mode-set registers.  There are quite a 
  455.  
  456. number of them and for the most part they're pretty boring.  By sending 
  457.  
  458. different values to these registers you can achieve the various video modes 
  459.  
  460. that your card is capable of.  These registers set values such as horizontal 
  461.  
  462. and vertical resolution, retrace timing, addressing modes, color depth, timing, 
  463.  
  464. and other fun stuff.  The truth is that it's easier and just as effective to
  465.  
  466. let the BIOS (gasp!) handle setting the screen mode for you, particularly since 
  467.  
  468. most games use standard modes such as 320x200 anyway.  At the very least you 
  469.  
  470. can let BIOS set the mode to begin with and then just modify the registers to 
  471.  
  472. "tweak" the mode the way you want it.  Any of these non-BIOS modes are 
  473.  
  474. generally refered to as mode X.  I don't want to go deep into detail on the 
  475.  
  476. setting and usage of mode X because there is already so much info availible on 
  477.  
  478. the topic.  Check out the Mode X Faq (regularly posted in comp.sys.ibm.pc.demos 
  479.  
  480. and rec.games.programmer), Micheal Abrash's collumn in Dr. Dobb's and his 
  481.  
  482. X-sharp library, or the section on mode X in the PC-GPE.
  483.  
  484.    One mode register I'll cover quickly is the chain-4 enable/disable.  A lot 
  485.  
  486. of programmers seem to have trouble visualizing what this thing does exactly. 
  487.  
  488. Bit 3 of port 3C4h (index 4) controls chain-4 mode.  Normally it is on.  This 
  489.  
  490. allows fast linear addressing of the bytes in video memory, which is the way 
  491.  
  492. you are probably used to addressing them.  For example, to change the second 
  493.  
  494. pixel on the screen to a certain color, you simply write the value to address 
  495.  
  496. A000:0001.  With chain-4 disabled (the main feature of mode X besides better 
  497.  
  498. resolution) A000:0000 refers to the first pixel in the upper-left corner of 
  499.  
  500. your screen, A000:0001 refers to the fourth pixel, A000:0002 to the eight pixel 
  501.  
  502. and so on.  The odd pixels are accessed by changing the write plane.  Since 
  503.  
  504. there are four planes, you effectively get an extra two bits of addressing 
  505.  
  506. space, boosting the total bit width for your pixel addressing from 16 to 18.  
  507.  
  508. Standard chain-4 four only allows access to 64K of memory (2^16) while 
  509.  
  510. disabling this feature gives you the full 256K (2^18) of memory to work with.  
  511.  
  512. The disadvantage, of course, is that pixel writes are slower due to the port 
  513.  
  514. writes required to access odd pixels.  How can this be an advantage?  For one 
  515.  
  516. thing, you can write four pixels at a time as long as they are all the same 
  517.  
  518. color - handy for single-color polygons, as in flight simulators.  Secondly, 
  519.  
  520. you get four times as much memory.  This allows you to have higher resolutions 
  521.  
  522. without bank switching, or scroll the screen using hardware scrolling, or do 
  523.  
  524. page flipping for smooth animation.  And since you can change the resolution, 
  525.  
  526. you can give yourself a sqaure aspect ration (320x240) which is better for 
  527.  
  528. bitmap rotations and the like.  But remember that it can be slower for 
  529.  
  530. bitmapped graphics because you have to do at least four writes to the card (to 
  531.  
  532. change planes) in order to copy bitmaps from main RAM to video memory.  Don't 
  533.  
  534. use mode X just because you think it's "cool"; make sure you have a good reason 
  535.  
  536. for wanting to use it in your program, or otherwise you're wasting a lot of 
  537.  
  538. effort for no reason.
  539.  
  540.  
  541.    Now, I'm sure you want me to continue until I divulge all the secrets of the 
  542.  
  543. VGA register to you - but, I only have some much time and space.  Besides, I 
  544.  
  545. still haven't uncovered all of their mysteries and capabilities myself.  
  546.  
  547. However, below is a list of the registers which you may want to play with for 
  548.  
  549. various effects.  The following list was posted on rec.games.programmer by 
  550.  
  551. Andrew Bromage (bromage@mundil.cs.mu.OZ.AU), so thanks to him for posting in to 
  552.  
  553. begin with.
  554.  
  555.    That's it for this article and I hope it helped you understand your VGA card 
  556.  
  557. a little better.  If not, re-read it, and try writing your own programs which 
  558.  
  559. use the registers.  The only way to really understand it (as with most things) 
  560.  
  561. is to get some hands-on experience.
  562.  
  563.    If you've got any questions, comments, flames, or corrections related to 
  564.  
  565. this document or game programming/design in general, feel free to post an 
  566.  
  567. article in rec.games.programmer (in case you haven't noticed by now, I hang out 
  568.  
  569. there regularly) or send mail to boone@ucsd.edu.
  570.  
  571.  
  572. Here's the list.  Have fun...
  573.  
  574.  
  575.           Documentation Over the I/O Registers for Standard VGA Cards
  576.  
  577.  
  578.                     Documentated by Shaggy of The Yellow One
  579.  
  580.                            Email: D91-SJD@TEKN.HJ.SE
  581.  
  582.  
  583. Feel free to spread this to whoever wants it.....
  584.  
  585. ------------------------------------------------------------
  586.  
  587. Port-Index:  -               Port: Write/03c2h Read/03cch
  588.  
  589. usage:       d7   Vertical sync polarity
  590.  
  591.              d6   Horizontal sunc polarity
  592.  
  593.              d5   Odd /even page
  594.  
  595.              d4   Disable video
  596.  
  597.              d3   Clock select 1
  598.  
  599.              d2   Clock select 0
  600.  
  601.              d1   Enable/Disable display RAM
  602.  
  603.              d0   I/O address select
  604.  
  605. Description: Sync polarity: Bits are set as below for VGA displays
  606.  
  607.              that use sync polarity to determine screen resolution.
  608.  
  609.              Many newer multiple frequency displays are insensitive
  610.  
  611.              to sync polarity
  612.  
  613.  
  614.              d7 d6      Resolution
  615.  
  616.              0  0       Invalid
  617.  
  618.              0  1       400 lines
  619.  
  620.              1  0       350 lines
  621.  
  622.              1  1       480 lines
  623.  
  624.  
  625.              I/O address select: When set to zero, selects the
  626.  
  627.              monochrome I/O address space (3bx). When set to one,
  628.  
  629.              it selects the color I/O address space (3dx)
  630.  
  631.  
  632. ------------------------------------------------------------
  633.  
  634. Port-Index: -                Port: 03c2h ; read only
  635.  
  636. usage:      d7    Vertical Retrace Interrupt pendling
  637.  
  638.             d6    Feature connector bit 1
  639.  
  640.             d5    Feature connector bit 0
  641.  
  642.             d4    Switch sense
  643.  
  644.             d0-d3 Unused
  645.  
  646.  
  647. Description: d7 uses IRQ2
  648.  
  649.  
  650. ------------------------------------------------------------
  651.  
  652. Port-Index: -                Port: 03bah,03dah ; read only
  653.  
  654. usage:      d3  Vertical retrace
  655.  
  656.             d0  Horizontal retrace
  657.  
  658.  
  659. ------------------------------------------------------------
  660.  
  661. Port-Index: -                Port: 03c3h,46e8h
  662.  
  663. usage:      d7-d1  Reserved
  664.  
  665.             d0     VGA enable/disable (03c3h only)
  666.  
  667.  
  668. Description: Disables access to display memmory and the other
  669.  
  670.              VGA's ports
  671.  
  672.  
  673. ------------------------------------------------------------
  674.  
  675. Port-Index: 00h              Port: 03d4h, 03b4h
  676.  
  677. usage:      Horizontal total
  678.  
  679. Description: Total number of characters in horizontal scan minus
  680.  
  681.              five ( including blanked and border characters)
  682.  
  683.  
  684. ------------------------------------------------------------
  685.  
  686. Port-Index: 01h              Port: 03d4h, 03b4h
  687.  
  688. usage:      Horizontal display enable
  689.  
  690. Description: Total number of characters displayed in horizontal
  691.  
  692.              scan minus one.
  693.  
  694. ------------------------------------------------------------
  695.  
  696. Port-Index: 02h              Port: 03d4h, 03b4h
  697.  
  698. usage:      Start horizontal blanking
  699.  
  700. Description: Character at which blanking starts
  701.  
  702.  
  703. ------------------------------------------------------------
  704.  
  705. Port-Index: 03h              Port: 03d4h, 03b4h
  706.  
  707. usage:      End horizontal blanking
  708.  
  709.             d7    Test
  710.  
  711.             d6    Skew control
  712.  
  713.             d5    Skew control
  714.  
  715.             d0-d4 End blanking
  716.  
  717. Description: End blanking: is five LSB bits of six-bit value,
  718.  
  719.              which define the character at which blanking stops.
  720.  
  721.              The MSB bit of this value is in register index 5.
  722.  
  723.  
  724. ------------------------------------------------------------
  725.  
  726. Port-Index: 04h              Port: 03d4h, 03b4h
  727.  
  728. usage:      Start horizontal retrace
  729.  
  730. Description: Character at which horizontal retrace starts
  731.  
  732.  
  733. ------------------------------------------------------------
  734.  
  735. Port-Index: 05h              Port: 03d4h, 03b4h
  736.  
  737. usage:      End horizontal retrace
  738.  
  739.             d7    End horizontal blanking bit 5
  740.  
  741.             d6    Horizontal retrace delay
  742.  
  743.             d5    Horizontal retrace delay
  744.  
  745.             d0-d4 End horizontal retrace
  746.  
  747. Description: End horizontal retrace: defines the character at
  748.  
  749.              which horizontal retrace ends
  750.  
  751.  
  752. ------------------------------------------------------------
  753.  
  754. Port-Index: 06h              Port: 03d4h, 03b4h
  755.  
  756. usage:      Vertical total
  757.  
  758. Description: Total number of horizontal scan lines minus two
  759.  
  760.              (including blanked and border characters). MSB bits
  761.  
  762.              of this value are in register index 7
  763.  
  764.  
  765. ------------------------------------------------------------
  766.  
  767. Port-Index: 07h              Port: 03d4h, 03b4h
  768.  
  769. usage:      Overflow register
  770.  
  771.             d7  Vertical retrace start (bit 9)
  772.  
  773.             d6  Vertical display enable end (bit 9)
  774.  
  775.             d5  Vertical total (bit 9)
  776.  
  777.             d4  Line compare (bit 8)
  778.  
  779.             d3  Start vertical blank (bit 8)
  780.  
  781.             d2  Vertical retrace start (bit 8)
  782.  
  783.             d1  Vertical display enable end (bit 8)
  784.  
  785.             d0  Vertical total (bit 8)
  786.  
  787. ------------------------------------------------------------
  788.  
  789. Port-Index: 08h              Port: 03d4h, 03b4h
  790.  
  791. usage:      Preset row scan
  792.  
  793.             d7    Unused
  794.  
  795.             d6    Byte panning control
  796.  
  797.             d5    Byte panning control
  798.  
  799.             d0-d4 Preset row scan
  800.  
  801. Description: Byte panning control: is used to control byte
  802.  
  803.              panning. This register together with attribute
  804.  
  805.              controller register 13h allows for up to 31 pixels of
  806.  
  807.              panning in double word modes
  808.  
  809.              Preset row scan: Which character scan line is the
  810.  
  811.              first to be displayed
  812.  
  813. ------------------------------------------------------------
  814.  
  815. Port-Index: 09h              Port: 03d4h, 03b4h
  816.  
  817. usage:      Maximum scan line/Character height
  818.  
  819.             d7    double scan
  820.  
  821.             d6    bit d9 of line compare register
  822.  
  823.             d5    bit d9 of start vertical blank register
  824.  
  825.             d0-d4 Maximum scan line
  826.  
  827. Description: d0-d5=Character height-1,  only in textmodes
  828.  
  829. ------------------------------------------------------------
  830.  
  831. Port-Index: 0ah              Port: 03d4h, 03b4h
  832.  
  833. usage:      Cursor start
  834.  
  835.             d7,d6 Reserved (0)
  836.  
  837.             d5    Cursor off
  838.  
  839.             d4-d0 Cursor start
  840.  
  841. Description:
  842.  
  843. ------------------------------------------------------------
  844.  
  845. Port-Index: 0bh              Port: 03d4h, 03b4h
  846.  
  847. usage:      Cursor end
  848.  
  849.             d7    reserved
  850.  
  851.             d6,d5 Cursor skew
  852.  
  853.             d4-d0 Cursor end
  854.  
  855. Description:
  856.  
  857. ------------------------------------------------------------
  858.  
  859. Port-Index: 0ch              Port: 03d4h, 03b4h
  860.  
  861. usage:      Start address high
  862.  
  863. ------------------------------------------------------------
  864.  
  865. Port-Index: 0dh              Port: 03d4h, 03b4h
  866.  
  867. usage:      Start address low
  868.  
  869. Description: Determine the offset in display memory to be
  870.  
  871.              displayed on the upper-left corner on the screen
  872.  
  873. ------------------------------------------------------------
  874.  
  875. Port-Index: 0eh              Port: 03d4h, 03b4h
  876.  
  877. usage:      Cursor location (high byte)
  878.  
  879. ------------------------------------------------------------
  880.  
  881. Port-Index: 0fh              Port: 03d4h, 03b4h
  882.  
  883. usage:      Cursor location (low byte)
  884.  
  885. Description: Where the cursor is displayed on screen
  886.  
  887. ------------------------------------------------------------
  888.  
  889. Port-Index: 10h              Port: 03d4h, 03b4h
  890.  
  891. usage:      Vertical retrace start
  892.  
  893. Description: 8 bits out of 10
  894.  
  895. ------------------------------------------------------------
  896.  
  897. Port-Index: 11h              Port: 03d4h, 03b4h
  898.  
  899. usage:      Vertical retrace end
  900.  
  901.             d7    Write protect CRTC register 0 to 7
  902.  
  903.             d6    refresh cycle select
  904.  
  905.             d5    enable vertical interrupt (when 0)
  906.  
  907.             d4    Clear vertical interrupt (when 0)
  908.  
  909.             d0-d3 Vertical retrace end
  910.  
  911. ------------------------------------------------------------
  912.  
  913. Port-Index: 12h              Port: 03d4h, 03b4h
  914.  
  915. usage:      Vertical display enable end
  916.  
  917. Description: eight LSB bits out of ten-bit value which define
  918.  
  919.              scan line minus one at which the display ends.
  920.  
  921.              The other two are in CRTC register index 7
  922.  
  923. ------------------------------------------------------------
  924.  
  925. Port-Index: 13h              Port: 03d4h, 03b4h
  926.  
  927. usage:      Offset / Logical screen width
  928.  
  929. Description: Logical screen width between successive scan lines
  930.  
  931. ------------------------------------------------------------
  932.  
  933. Port-Index: 14h              Port: 03d4h, 03b4h
  934.  
  935. usage:      Underline location register
  936.  
  937.             d7    Reserved
  938.  
  939.             d6    Double word mode
  940.  
  941.             d5    count by 4
  942.  
  943.             d0-d4 Underline location
  944.  
  945. Description: Underline location: Monochrome textmode only
  946.  
  947. ------------------------------------------------------------
  948.  
  949. Port-Index: 15h              Port: 03d4h, 03b4h
  950.  
  951. usage:      Start vertical blanking
  952.  
  953. Description: eight LSB bits of ten-bit value minus one which
  954.  
  955.              define at which scan line the vertical blanking
  956.  
  957.              starts. The other two bits are in CRTC registers
  958.  
  959.              index 7 and 9
  960.  
  961. ------------------------------------------------------------
  962.  
  963. Port-Index: 16h              Port: 03d4h, 03b4h
  964.  
  965. usage:      End vertical blanking
  966.  
  967. Description: eight LSB bits of a value which determine the scan
  968.  
  969.              line after which vertical blanking ends.
  970.  
  971. ------------------------------------------------------------
  972.  
  973. Port-Index: 17h              Port: 03d4h, 03b4h
  974.  
  975. usage:      Mode control register
  976.  
  977.             d7  Enable vertical and hoizontal retrace
  978.  
  979.             d6  Byte mode (1), word mode (0)
  980.  
  981.             d5  Address wrap
  982.  
  983.             d4  Reserved
  984.  
  985.             d3  count by 2
  986.  
  987.             d2  multiple vertical by 2 (use half in
  988.  
  989.                 CRTC (8,10,12,14,18)
  990.  
  991.             d1  Select row scan counter (not used)
  992.  
  993.             d0  compatibilty mode support (enable interleave)
  994.  
  995. ------------------------------------------------------------
  996.  
  997. Port-Index: 18h              Port: 03d4h, 03b4h
  998.  
  999. usage:      Line compare register
  1000.  
  1001. Description: Split screen,  8 bit value out of a ten-bit value
  1002.  
  1003. ------------------------------------------------------------
  1004.  
  1005. Port-Index: 00h              Port: 03c4h
  1006.  
  1007. usage:      Reset register
  1008.  
  1009.             d7-d2 Reserved
  1010.  
  1011.             d1    Synchronous reset
  1012.  
  1013.             d0    Asynchronous reset
  1014.  
  1015. Description: Synchr. when set to zero, will halt and reset
  1016.  
  1017.              the sequencer at the end of its current cycle
  1018.  
  1019.              Asyncht. when set to zero, will immediatly halt
  1020.  
  1021.              and reset the sequencer. Data can be loss.
  1022.  
  1023. ------------------------------------------------------------
  1024.  
  1025. Port-Index: 01h              Port: 03c4h
  1026.  
  1027. usage:      Clock mode register
  1028.  
  1029.             d7,d6 Reserved
  1030.  
  1031.             d5    display off
  1032.  
  1033.             d4    Allow 32-bit Fetch (not used in standard modes)
  1034.  
  1035.             d3    Divide dot clock by 2 (used in some 320*200 modes)
  1036.  
  1037.             d2    Allow 16-bit fetch (used in mon graphics modes)
  1038.  
  1039.             d1    Reserved
  1040.  
  1041.             d0    Enable (0) 9 dot characters (mono text and 400-line)
  1042.  
  1043. Description: Display off: Will blank screen and give the cpu
  1044.  
  1045.              uninterrupted access the display memory.
  1046.  
  1047. ------------------------------------------------------------
  1048.  
  1049. Port-Index: 02h              Port: 03c4h
  1050.  
  1051. usage:      Color plane write enable register
  1052.  
  1053.             d7,d6 Reserved
  1054.  
  1055.             d3    Plane 3 Write enable
  1056.  
  1057.             d2    Plane 2 Write enable
  1058.  
  1059.             d1    Plane 1 Write enable
  1060.  
  1061.             d0    Plane 0 Write enable
  1062.  
  1063. Description:
  1064.  
  1065. ------------------------------------------------------------
  1066.  
  1067. Port-Index: 03h              Port: 03c4h
  1068.  
  1069. usage:      Character generator select register
  1070.  
  1071.             d7,d6 Reserved
  1072.  
  1073.             d5    Character generator table select A (MSB)
  1074.  
  1075.             d4    Character generator table select B (MSB)
  1076.  
  1077.             d3,d2 Character generator table select A
  1078.  
  1079.             d1,d0 Character generator table select B
  1080.  
  1081. Description: This register is only of interest if your software
  1082.  
  1083.              will be using multiple character sets. Either one
  1084.  
  1085.              or two character sets can be active. Table A selects
  1086.  
  1087.              the charcater with attribute d3 set to zero and
  1088.  
  1089.              Table B is the one with d3 set to one.
  1090.  
  1091. ------------------------------------------------------------
  1092.  
  1093. Port-Index: 04h              Port: 03c4h
  1094.  
  1095. usage:      Memory mode register
  1096.  
  1097.             d4-d7 Reserved
  1098.  
  1099.             d3    Chain 4 (address bits 0&1 to select plan, mode 13h)
  1100.  
  1101.             d2    Odd/even (address bit 0 to select plane 0&2 or   
  1102.  
  1103.                   1&3 text modes)
  1104.  
  1105.             d1    Extended memory (disable 64k modes)
  1106.  
  1107.             d0    Reserved
  1108.  
  1109. Description:
  1110.  
  1111. ------------------------------------------------------------
  1112.  
  1113. Port-Index: 00h              Port: 03ceh
  1114.  
  1115. usage:      Set / Reset register
  1116.  
  1117.             d7-d4 Reserved (0)
  1118.  
  1119.             d3    Fill data for plane 3
  1120.  
  1121.             d2    Fill data for plane 2
  1122.  
  1123.             d1    Fill data for plane 1
  1124.  
  1125.             d0    Fill data for plane 0
  1126.  
  1127. ------------------------------------------------------------
  1128.  
  1129. Port-Index: 01h              Port: 03ceh
  1130.  
  1131. usage:      Set / Reset enable register
  1132.  
  1133.             d7-d4 Reserved (0)
  1134.  
  1135.             d3    enable set/reset for plane 3 (1 = enable)
  1136.  
  1137.             d2    enable set/reset for plane 2 (1 = enable)
  1138.  
  1139.             d1    enable set/reset for plane 1 (1 = enable)
  1140.  
  1141.             d0    enable set/reset for plane 0 (1 = enable)
  1142.  
  1143. Description: Set/Reset enable defines which memory planes will
  1144.  
  1145.              receive fill data from set/reset register. Any plane
  1146.  
  1147.              that is disable for set/reset will be written with
  1148.  
  1149.              normal processor output data
  1150.  
  1151. ------------------------------------------------------------
  1152.  
  1153. Port-Index: 02h              Port: 03ceh
  1154.  
  1155. usage:      Color compare register
  1156.  
  1157.             d7-d4 Reserved
  1158.  
  1159.             d3    Color compare value for plane 3
  1160.  
  1161.             d2    Color compare value for plane 2
  1162.  
  1163.             d1    Color compare value for plane 1
  1164.  
  1165.             d0    Color compare value for plane 0
  1166.  
  1167. Description: one indicate that color is the same
  1168.  
  1169. ------------------------------------------------------------
  1170.  
  1171. Port-Index: 03h              Port: 03ceh
  1172.  
  1173. usage:      Data rotate / Function select register
  1174.  
  1175.             d7-d5 Resrved (0)
  1176.  
  1177.             d4,d3 Function select
  1178.  
  1179.             d2-d0 Rotate count
  1180.  
  1181.  
  1182.             d4 d3  Function
  1183.  
  1184.             0  0   Write data unmodified
  1185.  
  1186.             0  1   Write data ANDed with processor latches
  1187.  
  1188.             1  0   Write data ORed with processor latches
  1189.  
  1190.             1  1   Write data XORed with processor latches
  1191.  
  1192. Description: Rotation is made before writing data
  1193.  
  1194. ------------------------------------------------------------
  1195.  
  1196. Port-Index: 04h              Port: 03ceh
  1197.  
  1198. usage:      Read plane select register
  1199.  
  1200.             d7-d2 Reserved (0)
  1201.  
  1202.             d1,d0 Defines color plane for reading (0-3)
  1203.  
  1204. Description: Doesnt matter in color compare mode
  1205.  
  1206. ------------------------------------------------------------
  1207.  
  1208. Port-Index: 05h              Port: 03ceh
  1209.  
  1210. usage:      Mode register
  1211.  
  1212.             d7    Reserved (0)
  1213.  
  1214.             d6    256-colour mode
  1215.  
  1216.             d5    Shift register mode
  1217.  
  1218.             d4    Odd / Even mode
  1219.  
  1220.             d3    Color compare mode enable (1 = enable)
  1221.  
  1222.             d2    Reserved (0)
  1223.  
  1224.             d1,d0 Write mode
  1225.  
  1226.  
  1227.             d1 d0 Write mode
  1228.  
  1229.             0  0  Direct write (data rotate, set/reset may apply)
  1230.  
  1231.             0  1  Use processor latches as write data
  1232.  
  1233.             1  0  Color plane n (0-3) is filled with the value of
  1234.  
  1235.                   bit n in the write data
  1236.  
  1237.             1  1  Use (rotated) write data ANDed with Bit mask as
  1238.  
  1239.                   bit mask. Use set/reset as if set/reset was
  1240.  
  1241.                   enable for all planes
  1242.  
  1243. Description:
  1244.  
  1245. ------------------------------------------------------------
  1246.  
  1247. Port-Index: 06h              Port: 03ceh
  1248.  
  1249. usage:      Miscellaneous register
  1250.  
  1251.             d7-d4 Reserved
  1252.  
  1253.             d3-d2 Memory map
  1254.  
  1255.                   00 = A000h for 128k
  1256.  
  1257.                   01 = A000h for 64k
  1258.  
  1259.                   10 = B000h for 32k
  1260.  
  1261.                   11 = B800h for 32k
  1262.  
  1263.             d1    Odd/even enable (used in text modes)
  1264.  
  1265.             d0    Graphics mode enable
  1266.  
  1267. Description: Memory map defines the location and size of the
  1268.  
  1269.              host window
  1270.  
  1271. ------------------------------------------------------------
  1272.  
  1273. Port-Index: 07h              Port: 03ceh
  1274.  
  1275. usage:      Color don't care register
  1276.  
  1277.             d7-d4 Reserved (0)
  1278.  
  1279.             d3    Plane 3 don't care
  1280.  
  1281.             d2    Plane 2 don't care
  1282.  
  1283.             d1    Plane 1 don't care
  1284.  
  1285.             d0    Plane 0 don't care
  1286.  
  1287. Description: Color don't care is used in conjunction with color
  1288.  
  1289.              compare mode. This register masks particular planes
  1290.  
  1291.              from being tested during color compare cycles.
  1292.  
  1293. ------------------------------------------------------------
  1294.  
  1295. Port-Index: 08h              Port: 03ceh
  1296.  
  1297. usage:      Bitmask register
  1298.  
  1299. Description: The bitmask register is used to mask certain bit
  1300.  
  1301.              positons from being modified.
  1302.  
  1303. ------------------------------------------------------------
  1304.  
  1305. Port-Index: -                 Port: 03c0h both index and data
  1306.  
  1307. usage:      d7,d6 Reserved
  1308.  
  1309.             d5    Palette address source
  1310.  
  1311.                   0 = palette can be modified, screen is blanked
  1312.  
  1313.                   1 = screen is enable, palette cannot be modified
  1314.  
  1315.             d4-d0 Palette register address
  1316.  
  1317. Description: Palette register address selects which register of
  1318.  
  1319.              the attributes controller will be addres,sed by the
  1320.  
  1321.              next I/O write cycle
  1322.  
  1323. ------------------------------------------------------------
  1324.  
  1325. Port-Index: 00h-0fh          Port: 03c0h
  1326.  
  1327. usage:      Color palette register
  1328.  
  1329.             d6,d7 Reserved
  1330.  
  1331.             d5-d0 Color value
  1332.  
  1333. Description: not used in 256 color modes
  1334.  
  1335. ------------------------------------------------------------
  1336.  
  1337. Port-Index: 10h              Port: 03c0h
  1338.  
  1339. usage:      Mode control register
  1340.  
  1341.             d7  p4,p5 source select
  1342.  
  1343.             d6  pixel width
  1344.  
  1345.             d5  Horizontal panning compatibility
  1346.  
  1347.             d4  Reserved
  1348.  
  1349.             d3  Background intensify / enable blinking
  1350.  
  1351.             d2  Line graphics enable (text modes only)
  1352.  
  1353.             d1  display type
  1354.  
  1355.             d0  graphics / text mode
  1356.  
  1357. Description: p4,p5 source select: selects the source for video
  1358.  
  1359.               outputs p4 and p5 to the DACs. If set to zero, p4
  1360.  
  1361.               and p5 are driven from the palette registers (normal
  1362.  
  1363.               operation). If set to one, p4 and p5 video outputs
  1364.  
  1365.               come from bits 0 and 1 of the color select register.
  1366.  
  1367.              pixel width: is set to one in mode 13h (256-color mode)
  1368.  
  1369.              horizontal panning compatibility: enhances the
  1370.  
  1371.               operation of the line compare register of the CRT
  1372.  
  1373.               controller, which allows one section of the screen
  1374.  
  1375.               to be scrolled while another section remains stationary.
  1376.  
  1377.               When this bit is set to one, the stationary
  1378.  
  1379.               section of the screen will also be immune to horizontal
  1380.  
  1381.               panning.
  1382.  
  1383. ------------------------------------------------------------
  1384.  
  1385. Port-Index: 11h              Port: 03c0h
  1386.  
  1387. usage:      Screen border color
  1388.  
  1389. Description: In text modes, the screen border color register
  1390.  
  1391.              selects the color of the border that sorrounds the
  1392.  
  1393.              text display area on the screen. This is also referred
  1394.  
  1395.              to by IBM as overscan. Unfortunately, this feature
  1396.  
  1397.              does not work properly on EGA displays in 350-line
  1398.  
  1399.              modes.
  1400.  
  1401. ------------------------------------------------------------
  1402.  
  1403. Port-Index: 12h              Port: 03c0h
  1404.  
  1405. usage:      Color plane enable register
  1406.  
  1407.             d7,d6 Reserved
  1408.  
  1409.             d5,d4 Video status mux
  1410.  
  1411.             d3    Enable color plane 3
  1412.  
  1413.             d2    Enable color plane 2
  1414.  
  1415.             d1    Enable color plane 1
  1416.  
  1417.             d0    Enable color plane 0
  1418.  
  1419. Description:  The video status mux bits can be used in conjunction
  1420.  
  1421.              with the diagnostic bits of input status register 1
  1422.  
  1423.              to read palette registers. For the EGA, this is the
  1424.  
  1425.              only means available for reading the palette registers.
  1426.  
  1427.               Enable color planes can be used to enable or disable
  1428.  
  1429.              color planes at the input to the color lockup table.
  1430.  
  1431.              A zero in any of these bit positions will mask the
  1432.  
  1433.              data from that color plane. The effect on the display
  1434.  
  1435.              will be the same as if that color plane were cleared
  1436.  
  1437.              to all zeros.
  1438.  
  1439. ------------------------------------------------------------
  1440.  
  1441. Port-Index: 13h              Port: 03c0h
  1442.  
  1443. usage:      Horizontal panning register
  1444.  
  1445.             d7-d4 reserved
  1446.  
  1447.             d3-d0 Horizontal pan
  1448.  
  1449. Description: Horizontal pan allows the display to be shifted
  1450.  
  1451.              horizontally one pixel at a time.
  1452.  
  1453.  
  1454.              d3-d0      Number of pixels shifted to the left
  1455.  
  1456.                         0+,1+,2+     13h     Other modes
  1457.  
  1458.                         3+,7,7+
  1459.  
  1460.              0          1            0       0
  1461.  
  1462.              1          2            1       -
  1463.  
  1464.              2          3            2       1
  1465.  
  1466.              3          4            3       -
  1467.  
  1468.              4          5            4       2
  1469.  
  1470.              5          6            5       -
  1471.  
  1472.              6          7            6       3
  1473.  
  1474.              7          8            7       -
  1475.  
  1476.              8          9            -       -
  1477.  
  1478. ------------------------------------------------------------
  1479.  
  1480. Port-Index: 14h              Port: 03c0h
  1481.  
  1482. usage:      Color select register
  1483.  
  1484.             d7-d4 Reserved
  1485.  
  1486.             d3    color 7
  1487.  
  1488.             d2    color 6
  1489.  
  1490.             d1    color 5
  1491.  
  1492.             d0    color 4
  1493.  
  1494. Description:  Color 7 and color 6: are normally used as the high
  1495.  
  1496.              order bits of the eight-bit video color data from the
  1497.  
  1498.              attribute controller to the DACs. The only exceptions
  1499.  
  1500.              are 256-color modes
  1501.  
  1502.               Color 5 and color 4: can be used in place of the p5
  1503.  
  1504.              and p6 outputs from the palette registers (see mode
  1505.  
  1506.              control register - index 10h). In 16-color modes, the
  1507.  
  1508.              color select register can be used to rapidly cycle
  1509.  
  1510.              between sets of colors in the video DAC.
  1511.  
  1512. ------------------------------------------------------------
  1513.  
  1514. Port-Index: -                Port: 03c6h
  1515.  
  1516. usage:      Pixel mask register
  1517.  
  1518. Description: ???
  1519.  
  1520. ------------------------------------------------------------
  1521.  
  1522. Port-Index: -                Port: 03c7h
  1523.  
  1524. usage:      DAC state register (read-only)
  1525.  
  1526. Description: if d0 and d1 is set to zero it indicates that
  1527.  
  1528.              the lookup table is in a write mode
  1529.  
  1530. ------------------------------------------------------------
  1531.  
  1532. Port-Index: -                Port: 03c7h
  1533.  
  1534. usage:      Lookup table read index register (Write only)
  1535.  
  1536. Description: Used when you want to read the palette (set color
  1537.  
  1538.              number)
  1539.  
  1540. ------------------------------------------------------------
  1541.  
  1542. Port-Index: -                Port: 03c8h
  1543.  
  1544. usage:      Lookup table write index register
  1545.  
  1546. Description: Used when you want to change palette (set color
  1547.  
  1548.              number)
  1549.  
  1550. ------------------------------------------------------------
  1551.  
  1552. Port-Index: -                Port: 03c9h
  1553.  
  1554. usage:      Lookup table data register
  1555.  
  1556. Description: Read color value (Red-Green-Blue) or write same data.
  1557.  
  1558. ------------------------------------------------------------
  1559.  
  1560.